﻿using NHibernate;
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SimpleTasks.Persistence.Hibernate
{
   public class HibernateUnitOfWork : IUnitOfWork
   {
      private ISessionFactory _sessionFactory;
      private ISession _currentSession;

      public HibernateUnitOfWork(ISessionFactory sessionFactory)
      {
         Contract.Requires(sessionFactory != null);

         _sessionFactory = sessionFactory;
      }

      internal ISession CurrentSession
      {
         get { return _currentSession; }
      }

      public void Start()
      {
         Contract.Requires(_sessionFactory != null);

         _currentSession = _sessionFactory.OpenSession();
         _currentSession.FlushMode = FlushMode.Never;

         _currentSession.BeginTransaction();
      }

      public void Pause()
      {
         if (_currentSession !=null && _currentSession.Transaction.IsActive)
         {
            _currentSession.Transaction.Commit();
         }
      }

      public void FlushAndPause()
      {
         if (_currentSession != null && _currentSession.IsOpen)
         {
            if (_currentSession.Transaction != null && _currentSession.Transaction.IsActive)
            {
               _currentSession.Flush();
               _currentSession.Transaction.Commit();
            }
         }
      }

      public void Resume()
      {
         if (!_currentSession.IsConnected)
	      {
            _currentSession.Reconnect();
	      }

         _currentSession.BeginTransaction();
      }

      public void End()
      {
         if (_currentSession != null && _currentSession.IsOpen)
         {
            if (_currentSession.Transaction != null && _currentSession.Transaction.IsActive)
            {
               _currentSession.Flush();
               _currentSession.Transaction.Commit();
            }
         }
      }

      public void Abort()
      {
         if (_currentSession != null && _currentSession.IsOpen)
         {
            _currentSession.Close();
         }
      }
   }
}
